#ifndef __LIBC_STDDEF_H
#define __LIBC_STDDEF_H

#include "stdint.h"
#include "math.h"

#ifdef __cplusplus
extern "C"
{
#endif

// bool
#ifndef BOOLEAN
#ifndef __cplusplus
#define BOOLEAN char
#else
#define BOOLEAN _Bool
#endif

#ifndef TRUE
#define true 1
#endif

#ifndef FALSE
#define false 0
#endif
#endif

#ifndef _WCHAR_T_DEFINED
#define _WCHAR_T_DEFINED
    typedef uint16_t wchar_t;
#endif

#define NULL ((void *)0)

#define write_once(var, val) \
    (*((volatile typedef(val) *)(&(var))) = (val))

#define offsetof(TYPE, MEMBER) ((uintptr_t)(&((TYPE *)0)->MEMBER))

    // according member point,struct type,member name,we get to owner point
#define container_of(ptr, type, member) (                 \
    {                                                     \
        const typeof(((type *)0)->member) *_mptr = (ptr); \
        (type *)((char *)_mptr - offsetof(type, member)); \
    })

#define IN_RANGE(x, a, b) (((x) > (a)) && ((x) < (b)))
#define OUT_RANGE(x, a, b) (((x) < (a)) || ((x) < (b)))

#ifndef MAX_PATH_LEN
#define MAX_PATH_LEN 256
#endif

#define max(a, b) (((a) > (b)) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))
#define clamp(v, a, b) min(max(a, v), b)

#define DIV_ROUND_UP(x, step) ((x + step - 1) / (step))
#define DIR_ROUND_DOWN(x, step) ((x) / (step))

#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#endif

#ifdef __cplusplus
}
#endif
#endif